home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of Down Under Games
/
The Best of Down Under Games.iso
/
3dfx Screen Savers
/
Impact
/
IMPSRC.ZIP
/
LAND.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-07-24
|
15KB
|
471 lines
#include "winstuff.h"
#include "land.h"
#include "trigs.h"
#include "things.h"
#include "stdio.h"
#include <math.h>
char MyS[256];
/*const int vertsep = 1024;
const int tdx = 4,tdz = 4;
const int gridsep = vertsep*(tdx);
const int GridNum = 32;*/
int frameCount;
float map[specwidth][specwidth];
entity_t *Self, *Other, *Head;
land_t::land_t(){
//Start = Trans = 0;
//Rects = Water = 0;
//Water = 0;
id = -1;
minx = 0;
minz = 0;
maxx = 0;
maxz = 0;
centerx = 0;
centerz = 0;
numland = 0;
numwater = 0;
NumLand++;
}
land_t::land_t(float x, float z, int mid){
generate(x,z,mid);
NumLand++;
}
land_t::~land_t(){
Print("destructor");
return;
//if(Start) delete Start;
//if(Trans) delete Trans;
//if(Rects) delete Rects;
//if(Water) delete Water;
//NumLand--;
}
land_t::render(Matrix rot, float x, float y, float z){
int render = 0,Realr=0,gridsep2 = gridsep/2,gridsep3 = gridsep*2;//,gridsep3 = gridsep2;//<<1;
int cnt=4,cnt2=0,hitthat;
int i,j,k,l;
float x1,y1,z1;
GrVertex Cen;
Matrix yawcam;
// Camzoomx,Camzoomy;
rendered = render;
if(x < minx-gridsep2 || x > maxx+gridsep2 || z < minz-gridsep2 || z > maxz+gridsep2){
for(cnt = 0;cnt<5 && render == 0;cnt++){
x1 = pntx[cnt];// - x;
z1 = pntz[cnt];// - z;
if(x1*Tridz[0]+z1*Tridx[0]<Trib[0] &&
x1*Tridz[1]+z1*Tridx[1]<Trib[1] &&
x1*Tridz[2]+z1*Tridx[2]<Trib[2])
render = 1;
}
}
else
render = 2;
rendered = render;
if (render){
if(!Start) return 0;
//cnt = firstreal;
//cnt2=0;
for(cnt = 0;cnt<vertscnt;cnt++){
hitthat = MyVerts[cnt];
if(Start[hitthat].oow <GameTime){
Trans[hitthat].x = Start[hitthat].x - x;
Trans[hitthat].y = Start[hitthat].y - y;
Trans[hitthat].z = Start[hitthat].z - z;
//Trans[cnt].a=255;
//Trans[hitthat].r = Start[hitthat].r;
//Trans[hitthat].g = Start[hitthat].g;
//Trans[hitthat].b = Start[hitthat].b;
lit[hitthat].r = .75;
lit[hitthat].g = .75;
lit[hitthat].b = .75;
PointMatMult(&Trans[hitthat],&Trans[hitthat],rot);
Trans[hitthat].ooz =
Trans[hitthat].oow = 1/Trans[hitthat].z;
Trans[hitthat].x = Camzoomx*Trans[hitthat].x*Trans[hitthat].ooz+wHWidth+vertex_snapper;
Trans[hitthat].y = Camzoomy*Trans[hitthat].y*Trans[hitthat].ooz+wHHeight+vertex_snapper;
Trans[hitthat].x -=vertex_snapper;
Trans[hitthat].y -=vertex_snapper;
}
}
Other = Head;
while(Other){
if(Other->light && Other->x > minx-gridsep3 && Other->x < maxx+gridsep3 && Other->z > minz-gridsep3 && Other->z < maxz+gridsep3)
castlight(Other);
Other = Other->next;
}
for(cnt = 0;cnt<vertscnt;cnt++){
hitthat = MyVerts[cnt];
if(Start[hitthat].oow < GameTime){
Trans[hitthat].r = Start[hitthat].r*lit[hitthat].r;
Trans[hitthat].g = Start[hitthat].g*lit[hitthat].g;
Trans[hitthat].b = Start[hitthat].b*lit[hitthat].b;
if(Trans[hitthat].r>255) Trans[hitthat].r = 255;
if(Trans[hitthat].g>255) Trans[hitthat].g = 255;
if(Trans[hitthat].b>255) Trans[hitthat].b = 255;
Start[hitthat].oow=GameTime;
}
}
//int tmp,xbig=0,ybig=0,xsml=0,ysml=0,hitthat;
for(cnt=0;cnt<sqrcnt;cnt++){
hitthat = MyRects[cnt];
i = Rects[hitthat].corn[0];
j = Rects[hitthat].corn[1];
k = Rects[hitthat].corn[2];
l = Rects[hitthat].corn[3];
AttCount+=2;
int back1=2,back2=2;
//Backface removal
if( Trans[i].z < 1 &&
Trans[j].z < 1 &&
Trans[k].z < 1 &&
Trans[l].z < 1)
continue;
if(
Trans[i].z >= 1 &&
Trans[j].z >= 1 &&
Trans[k].z >= 1 &&
Trans[l].z >= 1){
back1=(((Trans[j].x - Trans[i].x)*
(Trans[k].y - Trans[i].y)-
(Trans[j].y - Trans[i].y)*
(Trans[k].x - Trans[i].x))>0);
back2=(((Trans[l].x - Trans[k].x)*
(Trans[i].y - Trans[k].y)-
(Trans[l].y - Trans[k].y)*
(Trans[i].x - Trans[k].x))>0);
if(!back1 && !back2) continue;
}
if(Trans[i].z < 1 || Trans[k].z < 1) {
if(back1)
MyDrawTriangleTooClose(Trans[i], Trans[j],Trans[k],
Start[i],Start[j],Start[k],
rot, x, y, z);
if(back2)
MyDrawTriangleTooClose(Trans[k], Trans[l],Trans[i],
Start[k],Start[l],Start[i],
rot, x, y, z);
}
else if(Trans[j].z < 1) {
if(back1)
MyDrawTriangleTooClose(Trans[i], Trans[j],Trans[k],
Start[i],Start[j],Start[k],
rot, x, y, z);
/*if(Trans[l].z < 1)
MyDrawTriangleTooClose(Trans[k], Trans[l],Trans[i],
Start[k],Start[l],Start[i];
rot, x, y, z);
else*/
if(back2)
guDrawTriangleWithClip(&Trans[k],&Trans[l],&Trans[i]);
}
else if(Trans[l].z < 1) {
if(back1)
guDrawTriangleWithClip(&Trans[i],&Trans[j],&Trans[k]);
if(back2)
MyDrawTriangleTooClose(Trans[k], Trans[l],Trans[i],
Start[k],Start[l],Start[i],
rot, x, y, z);
}
else{
if(back1)
guDrawTriangleWithClip(&Trans[i],&Trans[j],&Trans[k]);
if(back2)
guDrawTriangleWithClip(&Trans[k],&Trans[l],&Trans[i]);
/* if(back1)
grDrawTriangle(&Trans[i],&Trans[j],&Trans[k]);
if(back2)
grDrawTriangle(&Trans[k],&Trans[l],&Trans[i]);*/
}
TryCount+=2;
//if(TryCount>600*frameCount) {delete Trans;return 0;}
}
//delete Trans;
}
return 1;
}
void land_t::castlight(entity_t *Other){
int tmp,rgb, cnt = vertscnt,hitthat;
float dist,dist2,rdx,rdy,rdz,inten,al2=Other->lighta*Other->lighth;
al2*=al2;
if(Other->light == 0) return;
for(tmp=0;tmp<cnt;tmp++){
hitthat = MyVerts[tmp];
if(Start[hitthat].oow <GameTime){
rdx = Other->x-Start[hitthat].x;
rdy = Other->y-Start[hitthat].y;
rdz = Other->z-Start[hitthat].z;
dist2 = rdx*rdx+rdy*rdy+rdz*rdz;
if(dist2>al2) continue;
dist= sqrt(dist2);
inten = Other->lighth-dist/Other->lighta;//(dist2/382.5-5*dist/3+255)/255;//((dist2/255-dist+255)/255);
lit[hitthat].r+=(Other->lightr*inten)/255;
lit[hitthat].g+=(Other->lightg*inten)/255;
lit[hitthat].b+=(Other->lightb*inten)/255;
//if(lit[hitthat].r>2) lit[hitthat].r = 2;
//if(lit[hitthat].g>2) lit[hitthat].g = 2;
//if(lit[hitthat].b>2) lit[hitthat].b = 2;
if(lit[hitthat].r<0) lit[hitthat].r = 0;
if(lit[hitthat].g<0) lit[hitthat].g = 0;
if(lit[hitthat].b<0) lit[hitthat].b = 0;
}
}
}
land_t::generate(float x, float z, int mid){
float dx,dz;
//int tdx=32,tdz = 32;
int hitx,hitz,cnt=0,clr,realx,realz;
int rect=tdx*tdz,mrec;
int colr,colg,colb,crn;
id = mid;
//Rects = new landrect_t[rect];
crn = 0;
minx = x;
minz = z;
maxx = x+gridsep;//+vertsep;
maxz = z+gridsep;//+vertsep;
pntx[4] = centerx = (minx+maxx)/2;
pntz[4] = centerz = (minz+maxz)/2;
pntx[0] = pntx[1] = minx;
pntx[2] = pntx[3] = maxx;
pntz[0] = pntz[2] = minz;
pntz[1] = pntz[3] = maxz;
pnty[0] = pnty[1] = pnty[2] = pnty[3] = pnty[4] = 0;
numland = rect;
numwater = 0;
mrec = 0;
for(cnt = 0;cnt<GridNum2*tdx*tdz;cnt++){
if(Rects[cnt].CentX > minx && Rects[cnt].CentX < maxx &&
Rects[cnt].CentZ > minz && Rects[cnt].CentZ < maxz){
MyRects[mrec] = cnt;
mrec++;
//if(mrec == sqrcnt)
// break;
}
}
//sprintf(MyS,"%i %i",mrec,sqrcnt);
//Print(MyS);
mrec = 0;
for(cnt = 0;cnt<width2;cnt++){
if(Start[cnt].x >= minx && Start[cnt].x <= maxx &&
Start[cnt].z >= minz && Start[cnt].z <= maxz){
MyVerts[mrec] = cnt;
mrec++;
if(mrec == vertscnt)
break;
}
}
return 1;
}
float Rand1(float base,int delta){
float i;
i=base+((random(2048))%delta)-(delta/2);
/*if (i<-128) i=-128; if (i>127) i=127;*/
return i;
}
void DoOffsetSquare(int width){
int row_offset = 0; // start at zero for first row
/* Get the memory (widthxwidth bytes) */
//map = new int[width][width];
/* base value = 0, byte values are -128..127 */
for (int i=0;i<width;i++) for (int j=0;j<width;j++) map[i][j]=random(256)-128;
for (int l = 0;l<1;l++) {
map[0][0] = random(128);
map[0][width-1] = random(128);
map[width-1][0] = random(128);
map[width-1][width-1] = random(128);
}
for ( int square_size = width; square_size > 1; square_size /= 2 ){
int random_range = square_size;
for ( int x1 = row_offset; x1 < width; x1 += square_size ){
for ( int y1 = row_offset; y1 < width; y1 += square_size ){
// Get the four corner points.
int x2 = (x1 + square_size) % width;
int y2 = (y1 + square_size) % width;
float i1 = map[x1][y1];
float i2 = map[x2][y1];
float i3 = map[x1][y2];
float i4 = map[x2][y2];
// Obtain new points by averaging the corner points.
float p1 = ((i1 * 9) + (i2 * 3) + (i3 * 3) + (i4)) / 16;
float p2 = ((i1 * 3) + (i2 * 9) + (i3) + (i4 * 3)) / 16;
float p3 = ((i1 * 3) + (i2) + (i3 * 9) + (i4 * 3)) / 16;
float p4 = ((i1) + (i2 * 3) + (i3 * 3) + (i4 * 9)) / 16;
// Add a random offset to each new point.
p1 = Rand1(p1, random_range);
p2 = Rand1(p2, random_range);
p3 = Rand1(p3, random_range);
p4 = Rand1(p4, random_range);
// Write out the generated points.
int x3 = (x1 + square_size/4) % width;
int y3 = (y1 + square_size/4) % width;
x2 = (x3 + square_size/2) % width;
y2 = (y3 + square_size/2) % width;
map [x3][y3] = p1;
map [x2][y3] = p2;
map [x3][y2] = p3;
map [x2][y2] = p4;
}
}
row_offset = square_size/4; // set offset for next row
}
float miny=map[0][0],maxy=map[0][0];
for (i=0;i<width;i++)
for (int j=0;j<width;j++) {
if(map[i][j]>maxy) maxy = map[i][j];
if(map[i][j]<miny) miny = map[i][j];
}
float difx = 2;//0;//256 / (maxy-miny);
//float difn = -256/miny;
sprintf(MyS,"%f %f %f",map[0][0],maxy,miny);
Print(MyS);
for (i=0;i<width;i++)
for (int j=0;j<width;j++){
map[i][j] = (map[i][j])*difx;
if((i == 0 || i == ::width-1 || j == 0 || j == ::width -1) && map[i][j]<1024)
map[i][j] = 1024;
if((i == 1 || i == ::width-2 || j == 1 || j == ::width -2) && map[i][j]<196)
map[i][j] = 196;
if((i == 2 || i == ::width-3 || j == 2 || j == ::width -3) && map[i][j]<16)
map[i][j] = 16;
}
//sprintf(MyS,"%f %f",map[0][0],maxy*difx-(maxy-miny));
//Print(MyS);
for (i=0;i<width;i++)
for (int j=0;j<width;j++) {
if(map[i][j]>maxy) maxy = map[i][j];
if(map[i][j]<miny) miny = map[i][j];
}
//sprintf(MyS,"%f %f %f",map[0][0],maxy,miny);
//Print(MyS);
}
void Genland(void){
int dx=GridNum,dz=GridNum,cx,cz,cnt=0;
DoOffsetSquare(specwidth);
int hitx,hitz,colg,colr,colb;
for(dz = 0;dz<width;dz++){
for(dx = 0;dx<width;dx++){
Start[cnt].x = dx*vertsep;
Start[cnt].z = dz*vertsep;
Start[cnt].y = map[dx][dz];
colg = Start[cnt].y;
if(colg > 255) colg = 255;
if(colg < 0) colg = 0;
colb = Start[cnt].y;
if(colb > 192)
colb = 4*colb - 768;
else if(colb>0 && colb<193)
colb = 0;
else if(colb <= 0) colb = -colb;
if(colb>255) colb = 255;
if(colb<0) colb = 255;
colr = Start[cnt].y;
if(colr > 192)
colr = 4*colr - 768;
else
colr = 5;
if(colr>255) colr = 255;
if(colr<32) colr = 32;
if(colg <32)
colg = 32;
if(colb < 32) colb = 32;
if(colr < 32) colr = 32;
Start[cnt].r = colr;
Start[cnt].g = colg;
Start[cnt].b = colb;
Start[cnt].a = 255;
Trans[cnt].a = 255;
cnt++;
}
}
int crn = 0;
for(cnt = 0;cnt<Bigsqrcnt;cnt++){
Rects[cnt].corn[0] = crn;
Rects[cnt].corn[1] = crn+1;
Rects[cnt].corn[2] = crn+width+1;
Rects[cnt].corn[3] = crn+width;
Rects[cnt].CentX = (
Start[Rects[cnt].corn[0]].x+
Start[Rects[cnt].corn[1]].x+
Start[Rects[cnt].corn[2]].x+
Start[Rects[cnt].corn[3]].x
)/4;
Rects[cnt].CentZ = (
Start[Rects[cnt].corn[0]].z+
Start[Rects[cnt].corn[1]].z+
Start[Rects[cnt].corn[2]].z+
Start[Rects[cnt].corn[3]].z
)/4;
//sprintf(MyS,"%i %i",Rects[cnt].CentX ,Rects[cnt].CentZ );
//Print(MyS);
crn++;
if((crn+1)%(width)==0)
crn++;
}//Find the real one and replace it.
dx=GridNum;
dz=GridNum;
cnt = 0;
for(cx = 0;cx<dx;cx++){
for(cz = 0;cz<dz;cz++){
land[cnt].generate(cx*gridsep,cz*gridsep,cnt);
cnt++;
}
}
/* for(cx = 0;cx<width;cx++)
delete map[cx];
delete *map;*/
}